package service.forkinjoin;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.RecursiveTask;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeBodyPart;

import service.FileUtil;

public class ForkSortMessages extends RecursiveTask<List<Message>> {

	private static final long serialVersionUID = -1092415796824205832L;
	private List<Message> listMessages;

	public ForkSortMessages(List<Message> listMessages) {
		this.listMessages = listMessages;
	}

	@Override
	protected List<Message> compute() {

		List<RecursiveTask<List<Message>>> tasks = new ArrayList<>();

		if (this.listMessages.size() <= Runtime.getRuntime().availableProcessors()) {
			try {
				this.listMessages.addAll(this.separateMessages());
				return this.listMessages;
			} catch (MessagingException | IOException e) {
				e.printStackTrace();
			}
		} else {

			int end = this.listMessages.size() / 2;
			tasks.add(new ForkSortMessages(new ArrayList<Message>(this.listMessages.subList(0, end))));
			end += this.listMessages.size() % 2 == 0 ? 0 : 1;
			tasks.add(new ForkSortMessages(new ArrayList<Message>(this.listMessages.subList(end, this.listMessages.size()))));
			this.join();
		}
		return listMessages;
	}

	private List<Message> separateMessages() throws MessagingException, IOException {

		for (Iterator<Message> iterator = this.listMessages.iterator(); iterator.hasNext();) {
			
			Message message = (Message) iterator.next();
			
			if ((this.hasNoAttachment(message.getContentType())) || (this.hasNoXmlAttachment(message))) {
				iterator.remove();
			}
		}
		
		return this.listMessages;
	}

	private boolean hasNoAttachment(String content) {
		return !content.contains("multipart/MIXED");
	}

	private boolean hasNoXmlAttachment(Message message) throws IOException, MessagingException {

		Multipart multipart = (Multipart) message.getContent();

		for (int i = 0; i < multipart.getCount(); i++) {

			MimeBodyPart mimeBodyPart = (MimeBodyPart) multipart.getBodyPart(i);

			if (Part.ATTACHMENT.equalsIgnoreCase(mimeBodyPart.getDisposition())) {

				if (FileUtil.isXmlFile(mimeBodyPart.getFileName())) {
					return false;
				}
			}
		}

		return true;
	}
}
